package daily_exercise;

import java.util.*;

public class Demo2 {

    // 2924. 找到冠军 II
    public int findChampion(int n, int[][] edges) {
        // ture 表示存在某个队伍比下标为 i 的队伍强
        boolean[] flag = new boolean[n];
        for (int[] e : edges) {
            flag[e[1]] = true;
        }

        int ret = -1;
        for (int i = 0; i < n; i++) {
            if(!flag[i]) {
                if (ret != -1) return -1;
                ret = i;
            }
        }
        return ret;
    }


    // 705. 设计哈希集合
    // 方法一：使用boolean数组，创建足够大的空间
//    class MyHashSet {
//        private boolean[] hash;
//
//        public MyHashSet() {
//            hash = new boolean[1000001];
//        }
//
//        public void add(int key) {
//            hash[key] = true;
//        }
//
//        public void remove(int key) {
//            if (hash[key]) hash[key] = false;
//        }
//
//        public boolean contains(int key) {
//            return hash[key];
//        }
//    }
    // 方法二：使用模拟哈希表的方法，采用链地址法解决冲突
    class MyHashSet {
        private List<Integer>[] set;
        private static final int bucket = 823;

        public MyHashSet() {
            set = new List[823];
            Arrays.setAll(set, i -> new LinkedList<>());
        }

        public void add(int key) {
            int index = key % bucket;
            if (set[index].isEmpty() || !set[index].contains(key)) {
                set[index].add(key);
            }
        }

        public void remove(int key) {
            Iterator<Integer> i = set[key % bucket].iterator();
            while (i.hasNext()) {
                Integer x = i.next();
                if (x == key) {
                    i.remove();
                    return;
                }
            }
        }

        public boolean contains(int key) {
            return set[key %bucket].contains(key);
        }
    }



    // 706. 设计哈希映射
    class MyHashMap {
        private class Pair {
            int key;
            int value;

            public Pair(){}
            public Pair(int key, int val) {
                this.key = key;
                this.value = val;
            }

            public void setKey(int key) { this.key = key;}
            public int getKey() {return key;}
            public void setValue (int val) {this.value = val;}
            public int getValue() {return value;}
        }

        private List<Pair>[] hashMap;
        private static final int bucket = 823;

        public MyHashMap() {
            hashMap = new List[bucket];
            Arrays.setAll(hashMap, i -> new LinkedList<>());
        }

        public void put(int key, int value) {
            List<Pair> list = hashMap[hash(key)];
            if (list.isEmpty()) {
                list.add(new Pair(key, value));
            } else {
                for (int i = 0; i < list.size(); i++) {
                    if (list.get(i).getKey() == key) {
                        list.get(i).setValue(value);
                        return;
                    }
                }
                list.add(new Pair(key, value));
            }
        }

        public int get(int key) {
            List<Pair> list = hashMap[hash(key)];
            Iterator<Pair> i = list.iterator();
            while (i.hasNext()) {
                Pair pair = i.next();
                if (pair.getKey() == key) {
                    return pair.getValue();
                }
            }
            return -1;
        }

        public void remove(int key) {
            List<Pair> list = hashMap[hash(key)];
            Iterator<Pair> i = list.iterator();
            while (i.hasNext()) {
                Pair pair = i.next();
                if (pair.getKey() == key) {
                    i.remove();
                    return;
                }
            }
        }

        private int hash(int key) {
            return key % bucket;
        }
    }


    // 2007. 从双倍数组中还原原数组
    public int[] findOriginalArray(int[] changed) {
        if (changed.length  % 2 == 1) return new int[0];

        Arrays.sort(changed);
        int n = changed.length;
        int[] res = new int[n / 2];
        boolean[] vis = new boolean[n];    // 统计访问过的结点

        int k = 0;
        for (int i = 0, j = 1; k < n / 2 && j < n; ) {
            while (j < n && changed[j] < changed[i] * 2) j++;
            if (j == n || changed[j] > changed[i] * 2) return new int[0];       // 没有找到翻倍后的数

            res[k++] = changed[i];
            vis[i] = vis[j] = true;

            while (i < n && vis[i]) i++;
            while (j < n && vis[j]) j++;
            if (i == j) j++;            // 保证 j 一定在 i 后面
        }

        return k == n / 2 ? res : new int[0];
    }



    // 39. 组合总和
    private List<Integer> path;
    private List<List<Integer>> res;

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        path = new ArrayList<>();
        res = new ArrayList<>();
        Arrays.sort(candidates);

        dfs(candidates, target, 0);
        return res;
    }

    private void dfs(int[] candidates, int target, int pos) {
        if (target == 0) {
            res.add(new ArrayList<>(path));
            return;
        }

        for (int i = pos; i < candidates.length; i++) {
            if (target - candidates[pos] < 0) break;
            path.add(candidates[i]);
            dfs(candidates, target - candidates[i], i);
            path.remove(path.size() - 1);
        }
    }




    // 216. 组合总和 III
    private List<List<Integer>> res2;
    private List<Integer> path2;

    public List<List<Integer>> combinationSum3(int k, int n) {
        res = new ArrayList<>();
        path = new ArrayList<>();

        dfs(1, k, n);
        return res;
    }

    private void dfs(int pos, int k, int target) {
        if (path.size() == k) {
            if (target == 0) res.add(new ArrayList<>(path));
            return;
        }

        for (int i = pos; i <= 9; i++) {
            if (target - i < 0) break;
            path.add(i);
            dfs(i + 1, k, target - i);
            path.remove(path.size() - 1);
        }
    }




    // 377. 组合总和 Ⅳ
    public int combinationSum4(int[] nums, int target) {
        // dp[i]: 在 nums 数组中，凑成和为 i 的元素组合的个数
        Arrays.sort(nums);
        int n = nums.length;
        int[] dp = new int[target + 1];
        dp[0] = 1;

        for (int i = 1; i <= target; i++) {
            for (int j = 0; j < n; j++) {
                if (i - nums[j] < 0) break;
                dp[i] += dp[i - nums[j]];
            }
        }
        return dp[target];
    }



    // 1052. 爱生气的书店老板
    public int maxSatisfied(int[] customers, int[] grumpy, int minutes) {
        int sum = 0, n = customers.length;
        for (int i = 0; i < n; i++)
            if (grumpy[i] != 1) sum += customers[i];

        int tmp = 0, res = 0;
        for (int left = 0, right = 0; right < n; right++) {
            if (grumpy[right] == 1) tmp += customers[right];

            if (right - left + 1 == minutes) {
                res = Math.max(res, sum + tmp);
                if (grumpy[left] == 1) tmp -= customers[left];
                left++;
            }
        }

        return res;
    }



    // 2385. 感染二叉树需要的总时间
    public int amountOfTime(TreeNode root, int start) {
        Map<Integer,Set<Integer>> hash = new HashMap<>();
        dfs(root, 0, hash);

        Queue<Integer> q = new LinkedList<>();
        q.offer(start);
        Set<Integer> vis = new HashSet<>();
        vis.add(start);
        int res = 0;
        while (!q.isEmpty()) {
            for (int i = q.size(); i-- > 0; ) {
                Integer t = q.poll();

                for (Integer x : hash.get(t)) {
                    if (!vis.contains(x)) {
                        q.offer(x);
                        vis.add(x);
                    }
                }
            }
            if (q.isEmpty()) break;
            res++;
        }
        return res;
    }

    private void dfs(TreeNode root, int parentVal, Map<Integer,Set<Integer>> hash) {
        if (root == null) return;
        hash.putIfAbsent(root.val, new HashSet<>());

        if (parentVal > 0) {
            hash.get(root.val).add(parentVal);
            hash.get(parentVal).add(root.val);
        }
        dfs(root.left, root.val, hash);
        dfs(root.right, root.val, hash);
    }




    // 2739. 总行驶距离
    public int distanceTraveled(int mainTank, int additionalTank) {
        int res = 0;
        while (mainTank >= 5) {
            res += 50;
            mainTank -= 5;
            if (additionalTank > 0) {
                mainTank++;
                additionalTank--;
            }
        }
        res += mainTank * 10;
        return res;
    }



    // 2639. 查询网格图中每一列的宽度
    public static int[] findColumnWidth(int[][] grid) {
        int n = grid.length, m = grid[0].length;
        int[] res = new int[m];

        for (int j = 0; j < m; j++) {
            for (int i = 0; i < n; i++) {
                int len = 0;
                if (grid[i][j] < 0) len++;
                for (int num = grid[i][j] / (int)Math.pow(10, res[j]); num != 0; num /= 10) {
                    len++;
                }
                if (len > res[j]) res[j] = len;
                System.out.println(len);
            }
        }

        return res;
    }



    // 1329. 将矩阵按对角线排序
    public int[][] diagonalSort(int[][] mat) {
        // 对每条对角线使用归并排序
        int n = mat.length, m = mat[0].length;
        int[][] res = new int[n][m];
        for (int i = 0; i < n; i++) {
            int x = i, y = 0;
            while (x < n && y < m) {
                x++;
                y++;
            }
            mergeSort(mat, i, 0, x - 1, y -1);
        }
        for (int j = 0; j < m; j++) {
            int x = 0, y = j;
            while (x < n && y < m) {
                x++;
                y++;
            }
            mergeSort(mat, 0, j, x - 1, y - 1);
        }
        return mat;
    }

    private void mergeSort(int[][] mat, int i, int j, int x, int y) {
        if (i >= x && j >= y) return;

        int midX = (i + x) / 2, midY = (j + y) / 2;
        mergeSort(mat, i, j, midX, midY);
        mergeSort(mat, midX + 1, midY + 1, x, y);

        int[] tmp = new int[x - i + 1];
        int k = 0, i1 = i, j1 = j, i2 = midX + 1, j2 = midY + 1;
        while (i1 <= midX && i2 <= x) {
            if (mat[i1][j1] <= mat[i2][j2]) tmp[k++] = mat[i1++][j1++];
            else tmp[k++] = mat[i2++][j2++];
        }
        while (i1 <= midX) tmp[k++] = mat[i1++][j1++];
        while (i2 <= x) tmp[k++] = mat[i2++][j2++];

        for (k = 0; i <= x; k++) {
            mat[i++][j++] = tmp[k];
        }
    }




    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        char[] s = in.next().toCharArray();

        // 1. 计算各个字母出现的次数并找到出现次数最多的字符
        int[] count = new int[26];
        int max = 0;
        char maxChar = 0;
        for (int i = 0; i < n; i++) {
            char ch = s[i];
            if (++count[ch - 'a'] > max) {
                max = count[ch - 'a'];
                maxChar = ch;
            }
        }
        // 如果 max > (n + 1) / 2,则说明一定不能重排
        if (max > (n + 1) / 2) {
            System.out.println("no");
            return;
        }


        // 2. 先对出现次数最多的字母进行重排
        char[] arr = new char[n];
        int k = 0;
        for (; max-- > 0; k += 2) {
            arr[k] = maxChar;
            count[maxChar - 'a']--;
        }

        // 3. 对剩下位置进行重排
        for (int i = 0; i < 26; i++) {
            if (count[i] == 0) continue;

            while (count[i]-- > 0) {
                if (k >= n) k = 1;
                arr[k] = (char)('a' + i);
                k += 2;
            }
        }
        System.out.println("yes");
        System.out.println(new String(arr));
    }
}
